package com.yl.drug_management.rabbitmq;

import com.rabbitmq.client.Channel;
import com.ruoyi.common.core.rabbitmq.RabbitMQ;
import com.ruoyi.common.core.rabbitmq.TestMQ;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class TestListener {
    /**
     * @Description: 动态创建队列
     * bindings为绑定路由key和队列和交换机, @QueueBinding内配置路由key,队列,交换机
     * key：路由key名称，生产者根据这个发送消息
     * value：@Queue 队列配置
     * -value：队列名
     * -durable：是否持久化，ps：必须和exchange内的durable都为true时才是真正的持久化
     * -arguments：配置死信队列，x-dead-letter-exchange私信队列交换机名称，x-dead-letter-routing-key私信队列路由key名称/也可以时队列名
     * exchange：交换机配置
     * -value：交换机名称
     * -durable：是否持久化，ps：必须和queue内的durable都为true时才是真正的持久化
     * -type：队列类型，默认为直连direct
     * -ignoreDeclarationExceptions：当任何异常发生时，RabbitAdmin将立即停止处理所有声明，会导致侦听器容器无法初始化，这个选项设置为true指示RabbitAdmin记录异常，并继续声明其他元素
     * 主键@Payload可以自动将消息转换为对象
     * @Author: 王晨阳
     * @Date: 2021/6/2-16:17
     */
    @RabbitListener(bindings = @QueueBinding(
            key = RabbitMQ.TEST_KEY_ROUTER,
            value = @Queue(value = RabbitMQ.TEST_KEY_QUEUE,
                    durable = "true",
                    arguments = {@Argument(name = "x-dead-letter-exchange", value = "dead-exchange-test")
                            , @Argument(name = "x-dead-letter-routing-key", value = "dead-queue-test")}),
            exchange = @Exchange(value = RabbitMQ.SERVICE_ONE_EXCHANGE,
                    durable = "true",
                    type = "direct",
                    ignoreDeclarationExceptions = "true")))
    public void test(@Payload TestMQ testMQ, Message message, Channel channel) {
        try {
            //处理业务。。。。。
            //应答：第一个参数deliveryTag:该消息的index,第二个参数multiple：是否批量.true:将一次性ack所有小于deliveryTag的消息。
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            //拒绝：basicReject方法拒绝deliveryTag对应的消息，第二个参数是否requeue，true则重新入队列，否则丢弃或者进入死信队列
            try {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }

    }

    @RabbitListener(bindings = @QueueBinding(
            key = "dead-queue-test",
            value = @Queue(value = "dead-queue", durable="true"),
            exchange = @Exchange(value = "dead-exchange-test",
                    durable="true",
                    type= "direct",
                    ignoreDeclarationExceptions = "true")))
    public void dead(@Payload TestMQ testMQ, Message message){
        System.out.println("dead:" +  testMQ.toString());
    }

}
